package presentation;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.StatisticalBarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.statistics.DefaultStatisticalCategoryDataset;

import com.toedter.calendar.JDateChooser;

import control.connector.ConRMI;

public class AnalasysPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JComboBox cityBox;
	private JPanel areaPanel;
	private GridBagConstraints constraints;
	private JComboBox zipCodeBox;

	private List<String> zipCodeKBH = new ArrayList<String>();
	private List<String> zipCodeOdense = new ArrayList<String>();
	private JSpinner weekChooser;
	private JDateChooser ChosenDate;
	private GregorianCalendar today;
	private JPanel chartPanel;
	private JComboBox subjectbox;

	public AnalasysPanel() {
		zipCodeKBH.addAll(Arrays.asList("ALL", "2500", "2700"));
		zipCodeOdense.addAll(Arrays.asList("ALL", "5000", "5200", "5210",
				"5220", "5230", "5240", "5250", "5260", "5270"));
		//System.out.println(Integer.parseInt(zipCodeModel.toString().valueOf(zipCodeOdense)));
		setLayout(new BorderLayout());
		chartPanel = new JPanel(new BorderLayout());
		add(createChartPanel(new ArrayList<Float>()), BorderLayout.CENTER);
		add(createMenuPanel(), BorderLayout.WEST);
	}

	private JPanel createChartPanel(List<Float> data) {
		chartPanel.add(new ChartPanel(createChart(createDataset(data))));
		chartPanel.setBorder(BorderFactory.createTitledBorder(null,
				"Statistics", TitledBorder.CENTER, TitledBorder.TOP));
		return chartPanel;
	}

	private JPanel createMenuPanel() {

		JPanel menuPanel = new JPanel();
		menuPanel.setBorder(BorderFactory.createTitledBorder(null, "Menu",
				TitledBorder.CENTER, TitledBorder.TOP));

		menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.Y_AXIS));
		menuPanel.add(createSubjectPanel());
		menuPanel.add(createAreaPanel());
		menuPanel.add(createPeriodPanel());
		menuPanel.add(createGeneratePanel());

		// menuPanel.setPreferredSize(new Dimension(250,400));
		return menuPanel;

	}

	private JPanel createGeneratePanel() {
		JPanel generatePanel = new JPanel();
		JButton generateButton = new JButton("Generate");
		//generateButton.addActionListener(new ActionListener() {
			//public void actionPerformed(ActionEvent e) {
			//	generateButtonActionPerformed();
			//}
		//});
		generatePanel.add(generateButton);
		return generatePanel;
	}

	// We don't need this
	/*
	protected void generateButtonActionPerformed() {
		if (subjectbox.getSelectedItem().equals("Orders")) {
			if (cityBox.getSelectedItem().equals("Odense")) {
				try {
				
				List<Float> avrg = ConRMI.getServer()
							.getStatistics(Integer.parseInt(weekChooser.getValue()
									.toString()),
									getDate(),
									getZipCodeFrom(),getZipCodeTo());

					System.out.println("liste lavet");
					chartPanel.removeAll();
					JFreeChart createChart = createChart(createDataset(avrg));
					createChart.setTitle("Chart of zipcode "
							+ zipCodeBox.getSelectedItem() + " with "
							+ weekChooser.getValue().toString()
							+ " weeks choosen");
					chartPanel.add(new ChartPanel(createChart));
					this.revalidate();
				} catch (Exception e) {
					JOptionPane.showMessageDialog(this, e.toString(), "Error",
							JOptionPane.ERROR_MESSAGE);
									}
			} else {
				JOptionPane.showMessageDialog(this, cityBox
						.getSelectedItem().toString()
						+ " is not implemented yet", "Info",
						JOptionPane.INFORMATION_MESSAGE);
			}
		} else {
			JOptionPane.showMessageDialog(this, subjectbox.getSelectedItem()
					.toString()
					+ " is not implemented yet", "Info",
					JOptionPane.INFORMATION_MESSAGE);
		}
	}*/
	
	private int getZipCodeFrom() {
		if(!zipCodeBox.getSelectedItem().toString().equals("ALL")){
			System.out.println(zipCodeBox.getSelectedItem().toString());
			return Integer.parseInt(zipCodeBox.getSelectedItem().toString());
			
		}
		else{
		return Integer.parseInt(zipCodeOdense.get(1).toString());
	}}
	
	private int getZipCodeTo() {
		if(!zipCodeBox.getSelectedItem().toString().equals("ALL")){
			return Integer.parseInt(zipCodeBox.getSelectedItem().toString());
			
		}
		else{
		return Integer.parseInt(zipCodeOdense.get(zipCodeOdense.size()-1).toString());
	}}

	private long getDate() {
		Calendar chosenDate = new GregorianCalendar();
		chosenDate.setTimeInMillis(ChosenDate.getCalendar().getTimeInMillis());
		Calendar today = new GregorianCalendar();
		long dayInMillis = 86400000;
		
		while(today.get(Calendar.DAY_OF_WEEK) != chosenDate.get(Calendar.DAY_OF_WEEK)){
			today.setTimeInMillis(today.getTimeInMillis()-dayInMillis);
			
		}
		today.set(Calendar.HOUR_OF_DAY,0);
		today.set(Calendar.MINUTE,0);
		today.set(Calendar.SECOND,0);
		System.out.println(today.getTime());
		return today.getTimeInMillis();
	}

	private JPanel createSubjectPanel() {
		JPanel subjectPanel = new JPanel();
		subjectPanel.setLayout(new GridBagLayout());
		JLabel subject = new JLabel("Subject:");

		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = new Insets(5, 10, 5, 10);
		constraints.gridx = 0;
		subjectPanel.add(subject, constraints);
		subjectbox = new JComboBox(new String[] { "Orders", "Waste time",
				"Customer waste time", "Load" });
		constraints.gridx++;
		subjectPanel.add(subjectbox, constraints);
		return subjectPanel;
	}

	private JPanel createAreaPanel() {
		areaPanel = new JPanel();
		areaPanel.setLayout(new GridBagLayout());
		Border titleBorder = new TitledBorder(BorderFactory
				.createLineBorder(Color.black), "Area", TitledBorder.CENTER,
				TitledBorder.TOP);
		areaPanel.setBorder(titleBorder);

		constraints = new GridBagConstraints();
		constraints.insets = new Insets(5, 10, 5, 10);
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		JLabel city = new JLabel("City:");
		city.setHorizontalAlignment(JLabel.RIGHT);
		areaPanel.add(city, constraints);
		cityBox = new JComboBox(new String[] { "Odense", "KBH", "osv" });
		constraints.gridx++;
		areaPanel.add(cityBox, constraints);

		constraints.gridy++;
		constraints.gridx = 0;
		JLabel zipCode = new JLabel("Zip code:");
		zipCode.setHorizontalAlignment(JLabel.RIGHT);
		areaPanel.add(zipCode, constraints);
		zipCodeBox = new JComboBox();

		cityBox.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				zipCodeBox.removeAllItems();
				if (cityBox.getSelectedItem().equals("KBH")) {
					for (String zipCode : zipCodeKBH) {
						zipCodeBox.addItem(zipCode);
					}
				}
				if (cityBox.getSelectedItem().equals("Odense")) {
					for (String zipCode : zipCodeOdense) {
						zipCodeBox.addItem(zipCode);
					}
				}
			}

		});
		constraints.gridx++;
		areaPanel.add(zipCodeBox, constraints);

		return areaPanel;
	}

	private JPanel createPeriodPanel() {
		JPanel periodPanel = new JPanel();
		periodPanel.setLayout(new GridBagLayout());
		Border titleBorder = new TitledBorder(BorderFactory
				.createLineBorder(Color.black), "Period", TitledBorder.CENTER,
				TitledBorder.TOP);
		periodPanel.setBorder(titleBorder);

		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = new Insets(5, 10, 5, 10);
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		JLabel city = new JLabel("From:");
		city.setHorizontalAlignment(JLabel.RIGHT);
		periodPanel.add(city, constraints);
		constraints.gridx++;
		ChosenDate = new JDateChooser(Calendar.getInstance().getTime());
		ChosenDate.setPreferredSize(new Dimension(150, 30));
		periodPanel.add(ChosenDate, constraints);

		constraints.gridy++;
		constraints.gridx = 0;
		JLabel zipCode = new JLabel("Weeks:");
		zipCode.setHorizontalAlignment(JLabel.RIGHT);
		periodPanel.add(zipCode, constraints);
		constraints.gridx++;
		weekChooser = new JSpinner(new SpinnerNumberModel(1, 1, 52, 1));
		weekChooser.setToolTipText("Number of weeks to make statistics of");
		ChosenDate.setPreferredSize(new Dimension(150, 30));
		periodPanel.add(weekChooser, constraints);

		return periodPanel;
	}

	private CategoryDataset createDataset(List<Float> data) {
		DefaultStatisticalCategoryDataset dataset = new DefaultStatisticalCategoryDataset();
		if (data.size() == 24) {
			System.out.println(data);
			dataset.add(data.get(0).doubleValue(), data.get(1).doubleValue(),
					"Row 1", "00-02");
			dataset.add(data.get(2).doubleValue(), data.get(3).doubleValue(),
					"Row 2", "02-04");
			dataset.add(data.get(4).doubleValue(), data.get(5).doubleValue(),
					"Row 3", "04-06");
			dataset.add(data.get(6).doubleValue(), data.get(7).doubleValue(),
					"Row 4", "06-08");
			dataset.add(data.get(8).doubleValue(), data.get(9).doubleValue(),
					"Row 5", "08-10");
			dataset.add(data.get(10).doubleValue(), data.get(11).doubleValue(),
					"Row 6", "10-12");
			dataset.add(data.get(12).doubleValue(), data.get(13).doubleValue(),
					"Row 7", "12-14");
			dataset.add(data.get(14).doubleValue(), data.get(15).doubleValue(),
					"Row 8", "14-16");
			dataset.add(data.get(16).doubleValue(), data.get(17).doubleValue(),
					"Row 9", "16-18");
			dataset.add(data.get(18).doubleValue(), data.get(19).doubleValue(),
					"Row 9", "18-20");
			dataset.add(data.get(20).doubleValue(), data.get(21).doubleValue(),
					"Row 10", "20-22");
			dataset.add(data.get(22).doubleValue(), data.get(23).doubleValue(),
					"Row 11", "22-24");

		}
		return dataset;
	}

	/**
	 * Creates a sample chart.
	 * 
	 * @param dataset
	 *            a dataset.
	 * 
	 * @return The chart.
	 */
	private JFreeChart createChart(CategoryDataset dataset) {

		// create the chart...
		JFreeChart chart = ChartFactory.createLineChart("", // chart title
				"Time", // domain axis label
				"Orders", // range axis label
				dataset, // data
				PlotOrientation.VERTICAL, // orientation
				false, // include legend
				true, // tooltips
				false // urls
				);

		// chart.setBackgroundPaint(Color.white);

		CategoryPlot plot = (CategoryPlot) chart.getPlot();
		plot.setBackgroundPaint(Color.lightGray);
		plot.setRangeGridlinePaint(Color.white);

		// customise the range axis...
		NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		rangeAxis.setAutoRangeIncludesZero(true);

		// customise the renderer...
		StatisticalBarRenderer renderer = new StatisticalBarRenderer();
		renderer.setErrorIndicatorPaint(Color.black);
		final GradientPaint gp0 = new GradientPaint(0.0f, 0.0f, Color.green,
				0.0f, 0.0f, Color.lightGray);
		final GradientPaint gp1 = new GradientPaint(0.0f, 0.0f, Color.blue,
				0.0f, 0.0f, Color.lightGray);
		final GradientPaint gp2 = new GradientPaint(0.0f, 0.0f, Color.red,
				0.0f, 0.0f, Color.lightGray);
		final GradientPaint gp3 = new GradientPaint(0.0f, 0.0f, Color.black,
				0.0f, 0.0f, Color.lightGray);
		renderer.setSeriesPaint(0, gp0);
		renderer.setSeriesPaint(1, gp0);
		renderer.setSeriesPaint(2, gp0);
		renderer.setSeriesPaint(3, gp0);
		renderer.setSeriesPaint(4, gp1);
		renderer.setSeriesPaint(5, gp1);
		renderer.setSeriesPaint(6, gp1);
		renderer.setSeriesPaint(7, gp1);
		renderer.setSeriesPaint(8, gp2);
		renderer.setSeriesPaint(9, gp2);
		renderer.setSeriesPaint(10, gp2);
		renderer.setSeriesPaint(11, gp2);
		// renderer.setLegendItemLabelGenerator(new
		// SOCRCategorySeriesLabelGenerator());
		renderer.setItemMargin(-5);
		plot.setRenderer(renderer);
		// OPTIONAL CUSTOMISATION COMPLETED.
		return chart;
	}

}
